package com.pervasa.demo.re.impl.data;

import com.pervasa.demo.re.impl.ReactivityEngine;

public class ComboEvent extends Event {

	private Event[] events = new Event[2];
	public enum Relation {AND, OR, DELAY};
	private enum State {INIT, TRIGGERED};
	private long time;
	private long triggerTime;
	private Relation relation;
	private State state;
	private ReactivityEngine env;
		
	public Event[] getEvents() {
		return events;
	}

	public long getTime() {
		return time;
	}

	public ComboEvent(String name, Event event, Event event2, Relation state, ReactivityEngine env) {
		super(name);
		this.events[0] = event;
		this.events[0].addEventListener(this);
		this.events[1] = event2;
		this.events[1].addEventListener(this);
		this.relation = state;
		this.time = 0;
		this.triggerTime = 0;
		this.env = env;
		this.state = State.INIT;
	}
	
	public ComboEvent(String name, Event event, Event event2, long time, ReactivityEngine env) {
		super(name);
		this.events[0] = event;
		this.events[0].addEventListener(this);
		this.events[1] = event2;
		this.events[1].addEventListener(this);
		this.relation = Relation.DELAY;
		this.time = time;
		this.triggerTime = 0;
		this.env = env;
		this.state = State.INIT;
	}

	@Override
	public void evaluate(Object arg) {
		boolean result = false;
		switch (relation) {
		case AND:
			if (events[0].isTriggered() && events[1].isTriggered()) {
				result = true;
			}
			break;
		case OR:
			if (events[0].isTriggered() || events[1].isTriggered()) {
				result = true;
			}
			break;
		case DELAY:
			if (state == State.INIT) {
				if (arg == events[0]) {
					if (events[0].isTriggered()) {
						state = State.TRIGGERED;
						triggerTime = events[0].getStartTime();
					}
					if (events[1].isTriggered()) {
						state = State.INIT;
						result = true;
					}
				}
			}
			else if (state == State.TRIGGERED) {
				
				if (arg == events[1]) {
					if (events[1].getStartTime() - triggerTime <= time * 1000) {
						result = true;
					}
				}
				else {
					state = State.INIT;
				}
			}
		default:
		}
		setTriggered(result); 
	}
	
	@Override
	public String getExpression() {
		String result = (events[0].getName() != null) ? events[0].getName() : events[0].getExpression();
		switch (relation) {
		case AND:
			result += " * ";
			break;
		case OR:
			result += " + ";
			break;
		case DELAY:
			result += " * " + time + " * ";
			break;
		}
		result += (events[1].getName() != null) ? events[1].getName() : events[1].getExpression();
		return result;
	}
}
